﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk;
using System.Configuration;
using Xrm;
using Microsoft.Crm.Sdk.Messages;
using System.Web.Services.Protocols;

namespace MSCRMSendReportInEmail
{
    class MSCrmMethods
    {
        //#region readonly data members
        //readonly string rDomainName = ConfigurationSettings.AppSettings["mscrmdomain"];
        //readonly bool rIsSsl = Convert.ToBoolean(ConfigurationSettings.AppSettings["isSSL"]);
        //readonly string rUserName = ConfigurationSettings.AppSettings["username"];
        //readonly string rPassword = ConfigurationSettings.AppSettings["password"];
        //readonly string rDomain = ConfigurationSettings.AppSettings["domain"];
        //readonly string rOrgName = ConfigurationSettings.AppSettings["orgname"];
        //#endregion  readonly data members

        //#region MSCRM data members
        //ServerConnection.Configuration config;
        //private OrganizationServiceProxy _serviceProxy;
        //#endregion MSCRM data members

        XrmServiceContext xrm;

        public MSCrmMethods()
        {
            //Uncomment the following line if using designed components 
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            // Obtain the target organization's Web address and client logon 
            // credentials from the user.
            //ServerConnection serverConnect = new ServerConnection();
            //config = serverConnect.GetServerConfiguration(rDomainName, rIsSsl, rOrgName, rUserName, rPassword, rDomain);
            try
            {
                xrm = new XrmServiceContext("Xrm");
            }
            catch
            {
                throw;
            }
        }

        /// <summary>
        /// crate attachment in crm related to email
        /// </summary>
        /// <param name="_emailId"></param>
        /// <param name="_encodedBody"></param>
        /// <param name="data"></param>
        public void CreateAttachment(Guid _emailId,string _encodedBody, ProgramUtil data)
        {           
            try
            {
                ActivityMimeAttachment _sampleAttachment = new ActivityMimeAttachment
                {
                    ObjectId = new EntityReference(Email.EntityLogicalName, _emailId),
                    ObjectTypeCode = Email.EntityLogicalName,
                    Subject = data.AttachmentSubject,
                    Body = _encodedBody,
                    FileName = data.FileName
                };

                xrm.AddObject(_sampleAttachment);
                xrm.SaveChanges();

            }
            catch
            {
                throw;
            }            
        }

        /// <summary>
        /// Creates email record in crm with subject and body of given template title name
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public Xrm.Email CreateEmailFromTemplate(ProgramUtil data)
        {
            Xrm.Email email = null;
            try
            {
                // Retrieve the user information.
                WhoAmIRequest whoAmIRequest = new WhoAmIRequest();
                WhoAmIResponse whoAmIResponse = (WhoAmIResponse)xrm.Execute(
                    whoAmIRequest);

                //Create email
                Xrm.Template template = xrm.TemplateSet.First(t => t.Title == data.EmailTemplateTitle);

                // Use the InstantiateTemplate message to create an e-mail message using a template.
                InstantiateTemplateRequest instTemplateReq = new InstantiateTemplateRequest
                {
                    TemplateId = template.Id,
                    ObjectId = whoAmIResponse.UserId,
                    ObjectType = SystemUser.EntityLogicalName
                };

                InstantiateTemplateResponse instTemplateResp = (InstantiateTemplateResponse)xrm.Execute(instTemplateReq);


                if (instTemplateResp != null)
                {
                    email = instTemplateResp.EntityCollection[0] as Email;

                    ActivityParty fromParty = new ActivityParty
                    {
                        PartyId = new Microsoft.Xrm.Client.CrmEntityReference(data.FromEntityLogicalName, new Guid(data.FromEntityId))
                    };

                    string[] toArray = data.To.Split(';');
                    List<ActivityParty> toActivityArray = new List<ActivityParty>();
                    foreach (string t in toArray)
                    {
                        Guid contactid = GetContactByEmail(t);
                        if (contactid != Guid.Empty)
                        {
                            toActivityArray.Add(new ActivityParty { PartyId = new Microsoft.Xrm.Client.CrmEntityReference(Xrm.Contact.EntityLogicalName, contactid) });
                        }
                        else
                        {
                            Guid systemuserId = GetSystemUserIdByEmail(t);
                            if (systemuserId != Guid.Empty)
                            {
                                toActivityArray.Add(new ActivityParty { PartyId = new Microsoft.Xrm.Client.CrmEntityReference(Xrm.SystemUser.EntityLogicalName, systemuserId) });
                            }
                        }
                    }

                    email.To =toActivityArray.ToArray();
                    email.From = new ActivityParty[] { fromParty };
                    email.DirectionCode = true;

                    xrm.AddObject(email);
                    xrm.SaveChanges();                    
                }
                else
                {
                    throw new MissingFieldException(String.Format("Failed To find template with Title = {0}", data.EmailTemplateTitle));
                }

            }
            catch
            {
                throw;
            }
            return email;
        }

        /// <summary>
        /// Send email from CRM
        /// </summary>
        /// <param name="_emailId">the guid of the email that needs to be sent</param>
        public void SendEmail(Guid _emailId)
        {
            try
            {
                // Use the SendEmail message to send an e-mail message.
                SendEmailRequest sendEmailreq = new SendEmailRequest
                {
                    EmailId = _emailId,
                    TrackingToken = "",
                    IssueSend = true
                };

                SendEmailResponse sendEmailresp = (SendEmailResponse)xrm.Execute(sendEmailreq);
            }
            catch
            {
                throw;
            }

        }

        private Guid GetSystemUserIdByEmail(string email)
        {
            try
            {
                //search system users
                var systemuser = xrm.SystemUserSet.First(s => s.InternalEMailAddress == email || s.PersonalEMailAddress == email);
                if (systemuser != null)
                {
                    return systemuser.Id;
                }
            }
            catch
            {

            }
            return Guid.Empty;
        }
        private Guid GetContactByEmail(string email)
        {
            try
            {
                var contact = xrm.ContactSet.First(a => a.EMailAddress1 == email || a.EMailAddress2 == email || a.EMailAddress3 == email);
                if (contact != null && contact.Id != Guid.Empty)
                {
                    return contact.Id;
                }
            }
            catch
            {
            }
            return Guid.Empty;
        }
    }
}
